//10. 复习类相关知识
//本⼩节是复习类相关知识，如果有相关基础可以跳过。
class Person_Class {
    name: string
    age: number
    //构造器
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    //方法
    speack() {
        console.log(`我叫：${this.name},今年${this.age}岁`)
    }
}

// const p1 = new Person_Class("张三", 18)
// console.log(p1)
// p1.speack()

//Student 继承 Person 
class Student extends Person_Class {
    grade: string
    //构造器
    constructor(name: string, age: number, grade: string) {
        //调用父类构造函数
        super(name, age)
        this.grade = grade
    }

    // ⼦类⾃⼰的⽅法
    study() {
        console.log(`${this.name}正在努力学习中.....`)
    }

    //覆盖父方法
    // speack() {
    //     console.log(`我叫：${this.name},今年${this.age}哈哈哈哈哈哈哈哈哈岁`)
    // }

    //重写父方法
    // 备注本例中若Student类不需要额外的属性，Student的构造器可以省略
    // 重写从⽗类继承的⽅法
    override speack() {
        console.log(`我叫：${this.name},今年${this.age}哈哈哈哈哈哈哈哈哈岁`)
    }
}

const s1 = new Student('李同学', 16, '高三')
console.log(s1)
s1.study()
s1.speack()





//11. 属性修饰符
//   修饰符          含义                  具体规则
//   public         公开的           可以被：类内部、⼦类、类外部访问 。
//  protected      受保护的           可以被：类内部、⼦类访问。
//   private        私有的             可以被：类内部访问。
//   readonly      只读属性              属性⽆法修改。

//public 修饰符    类内部、⼦类、类外部访问
class Person_Class2 {
    public name: string
    public age: number
    //构造器
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }

    //方法
    public speack() {
        console.log(`我叫：${this.name},今年${this.age}岁`)
    }
}

class Student2 extends Person_Class2 {
    // ⼦类⾃⼰的⽅法
    public study() {
        console.log(`${this.name}正在努力学习中.....`)
    }
}
const stu2 = new Person_Class2("张三", 18)
stu2.name
stu2.age
stu2.speack()

//属性的简写形式
// =====> 简写前
class Person_Class3 {
    public name: string
    public age: number
    //构造器
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
}
// =====> 简写后
class Person_Class4 {
    constructor(
        public name: string,
        public age: number
    ) { }
}
const st4 = new Person_Class4('麻子', 18)
// console.log(st4.age, st4.name)


//protected 修饰符    类内部、⼦类访问
class Person_Class5 {
    //简写形式
    constructor(
        protected name: string,
        protected age: number
    ) { }

    //方法
    //getDetails是受保护⽅法，不能在类外部访问，但可以在【类】与【⼦类】中访问
    protected getDetails() {
        return `我叫：${this.name},今年${this.age}岁`
    }

    introduce() {
        console.log(this.getDetails())
    }
}
//继承父类
class Student5 extends Person_Class5 {
    constructor(
        protected name: string,
        protected age: number,
        public id: string
    ) {
        super(name, age)
    }
    // ⼦类⾃⼰的⽅法
    public study() {
        console.log(this.getDetails(), `${this.name}正在努力学习中.....`)
    }
}

const stu5 = new Person_Class5('麻子', 18)
// stu5.introduce()
// stu5.getDetails()
// stu5.name
// stu5.age
const per5 = new Student5('麻子', 18, 'xxxx')
per5.study()


//private 修饰符
class Person6 {
    //简写形式
    constructor(
        public name: string,
        public age: number,
        // IDCard属性为私有的(private)属性，只能在【类内部】使⽤
        private IDCard: string
    ) { }

    private getPriviteInfo() {
        //// 类内部可以访问私有的(private)属性 —— IDCard
        return '身份证：' + this.IDCard
    }

    getinfo() {
        return `我叫：${this.name},今年${this.age}岁`
    }

    getFullInfo() {
        return this.getinfo() + ',' + this.getPriviteInfo()
    }
}

const per6 = new Person6("tom", 18, '10000000000000000000000000')
per6.name
per6.age
// per6.IDCard
// console.log(per6.getFullInfo())


//readonly 修饰符
class Person7 {
    //简写形式
    constructor(
        public name: string,
        //只读属性
        public readonly age: number,
    ) { }
}
const per7 = new Person7("tom", 18)
per7.name = "xxx"
// per7.age = 15


class Car {
    constructor(
        public readonly vin: string, //⻋辆识别码，为只读属性
        public readonly year: number,//出⼚年份，为只读属性
        public color: string,
        public sound: string
    ) { }
    // 打印⻋辆信息
    displayInfo() {
        console.log(`
    识别码：${this.vin},
    出⼚年份：${this.year},
    颜⾊：${this.color},
    ⾳响：${this.sound}
    `);
    }
}
const car = new Car('1HGCM82633A123456', 2018, '⿊⾊', 'Bose⾳响');
car.displayInfo()
// 以下代码均错误：不能修改 readonly 属性
// car.vin = '897WYE87HA8SGDD8SDGHF';
// car.year = 2020; 

